﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SWGeneracionE.Models;
using SWGeneracionE.Libraries;

namespace SWGeneracionE.Controllers
{
    public class BusController : BaseController
    {
        //
        // GET: /CheckinIda/

        [Authorize]
        public ActionResult CheckinIda()
        {
            return View();
        }

        //
        // GET: /CheckinVuelta/

        [Authorize]
        public ActionResult CheckinVuelta()
        {
            return View();
        }

        #region "Acciones de Checkin"
        [HttpPost]
        public JsonResult BusList(int jtStartIndex = 0, int jtPageSize = 0, string jtSorting = null)
        {
            try
            {
                var busesCount = 0;
                if (string.IsNullOrEmpty(jtSorting))
                    jtSorting = "noBus ASC";
                var buses = UoW.busRepository.GetAllPaging(ref busesCount, jtStartIndex, jtPageSize, jtSorting)
                    .Select(l => new
                    {
                        idBus = l.idBus,
                        noBus = l.NoBus,
                        descripcion = l.Descripcion,
                        estado = l.Estado,
                        capacidad = l.Capacidad
                    });

                return Json(new { Result = "OK", Records = buses, TotalRecordCount = busesCount });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error BusList: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrio un error al obtener el listado de buses." });
            }
        }

        [HttpPost]
        public JsonResult CreateBus(Bus bus)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    AgregarBitacora("Error CreateBus: Formulario inválido");
                    return Json(new
                    {
                        Result = "ERROR",
                        Message = "¡El formulario no es válido! " +
                        "Corrija e intente nuevemente."
                    });
                }

                UoW.busRepository.Add(bus);
                UoW.Save();
                var addedBus = new
                {
                    idBus = bus.idBus,
                    noBus = bus.NoBus,
                    descripcion = bus.Descripcion,
                    estado = bus.Estado,
                    capacidad = bus.Capacidad

                };
                AgregarBitacora("Creación de bus (CreateBus): " + addedBus.idBus.ToString());
                return Json(new { Result = "OK", Record = addedBus });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error CreateBus: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = ex.Message });
            }
        }

        [HttpPost]
        public JsonResult UpdateBus(Bus bus)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    AgregarBitacora("Error UpdateBus: Formulario inválido");
                    return Json(new
                    {
                        Result = "ERROR",
                        Message = "¡El formulario no es válido! " +
                        "Corrija e intente nuevemente."
                    });
                }

                UoW.busRepository.Edit(bus);
                UoW.Save();
                AgregarBitacora("Actualización de bus (UpdateBus): " + bus.idBus.ToString());
                return Json(new { Result = "OK" });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error UpdateBus: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrio un error al actualizar el bus." });
            }
        }

        [HttpPost]
        public JsonResult DeleteBus(int idBus)
        {
            try
            {
                Bus bus = UoW.busRepository.FindFirst(p => p.idBus == idBus);
                UoW.busRepository.Delete(bus);
                UoW.Save();
                AgregarBitacora("Eliminación de bus (DeleteBus): " + idBus.ToString());
                return Json(new { Result = "OK" });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error DeleteBus: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrio un error al eliminar el bus." });
            }
        }

        [HttpPost]
        public JsonResult GetEstadoOptions()
        {
            try
            {
                var estados = UoW.estadoBusRepository.GetAll().Select(
                                g => new { DisplayText = g.nombre, Value = g.idEstadoBus });
                return Json(new { Result = "OK", Options = estados });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error GetEstadoOptions: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al obtener listado de estados de bus." });
            }
        }

        public ExcelResult BusExportExcel(string idBus, string ruta)
        {
            try
            {
                //validar los 5 filtros
                int iBus = int.Parse(idBus);
                int iRuta = int.Parse(ruta);
                var consulta = UoW.busParticipanteRepository.FindBy(b => b.idBus == iBus && b.ruta == iRuta).ToList();

                var contador = consulta.Count;
                //se crea el objeto con los encabezados y datos que iran en la hoja de excel
                var excelData = new ExcelData();
                excelData.headers = new string[4];
                excelData.contents = new string[contador, 4];
                excelData.headers[0] = "No.";
                excelData.headers[1] = "Nombre Completo";
                excelData.headers[2] = "Tipo Documento";
                excelData.headers[3] = "No. Documento";

                var i = 1;
                //se llenan los datos según los obtenidos en la consulta
                foreach (var pasajero in consulta)
                {
                    Participante participante = pasajero.ParticipanteXEvento.Participante;
                    excelData.contents[i, 0] = i.ToString();
                    excelData.contents[i, 1] = participante.nombres + " " + participante.apellidos;
                    excelData.contents[i, 2] = participante.DocumentoXParticipante.First().TipoDocumentoID.nombre;
                    excelData.contents[i, 3] = participante.DocumentoXParticipante.First().noDocumento;

                    i++;
                }

                //Devolver vista parcial
                return new ExcelResult("BusGE.xls", PartialView("_ExcelTemplate", excelData));

            }
            catch (Exception ex)
            {
                AgregarBitacora("Error BusExportExcel: " + ex.Message + "--" + ex.Source);
                return null;
            }
        }
        #endregion

        #region "Acciones Pasajero"
        [HttpPost]
        public JsonResult CreatePasajero(BusParticipante pasajero)
        {
            try
            {
                ParticipanteXEvento participante = null;
                if (!ModelState.IsValid)
                {
                    AgregarBitacora("Error CreatePasajero: Formulario inválido");
                    return Json(new
                    {
                        Result = "ERROR",
                        Message = "¡El formulario no es válido! " +
                        "Corrija e intente nuevemente."
                    });
                }
                //comparar participante
                if (pasajero.codigo != null)
                {
                    participante = UoW.participanteXEventoRepository
                        .FindFirst(t => t.codigo == pasajero.codigo.Trim() && t.estado == Constantes.ESTADOPARTICIPANTE_INSCRITO);
                    if (participante != null)
                        pasajero.idParticipanteXEvento = participante.idParticipanteXEvento;
                    else
                    {
                        return Json(new
                        {
                            Result = "ERROR",
                            Message = "¡El participante que ha ingresado es inv&aacute;lido! <br/>" +
                                      "Corrija e intente nuevemente."
                        });
                    }
                }

                //que no hay sido asignado ya
                BusParticipante busp = UoW.busParticipanteRepository
                    .FindFirst(b => b.idParticipanteXEvento == pasajero.idParticipanteXEvento);
                if (busp != null)
                {
                    return Json(new
                    {
                        Result = "ERROR",
                        Message = "¡El participante que ha ingresado ya ha sido asignado a otro bus!" 
                    });
                }
                //que no exceda limite
                Bus bus = UoW.busRepository.FindFirst(b => b.idBus == pasajero.idBus);
                int cupo = UoW.busParticipanteRepository.FindBy(b => b.idBus == pasajero.idBus).Count();
                if (cupo >= bus.Capacidad)
                {
                    return Json(new
                    {
                        Result = "ERROR",
                        Message = "¡La capacidad del bus ha llegado al límite! <br/>"+
                                  "Ingrese al participante en el siguiente bus"
                    });
                }
                if (participante.Participante.DocumentoXParticipante.Count == 0)
                {
                    return Json(new
                    {
                        Result = "ERROR",
                        Message = "¡El participante no tiene asignado ningún Documento ID! <br/>"
                    });
                }

                //Insertar pasajero
                if (bus.BusParticipante.Count == (bus.Capacidad - 1))
                {
                    bus.Estado = Constantes.ESTADOBUS_CERRADO;
                    UoW.busRepository.Edit(bus);
                }
                UoW.busParticipanteRepository.Add(pasajero);
                UoW.Save();
                //seleccionar solo los campos que se necesitan, ya que los demás no pueden enviarse por Json
                var addedPasajero = new
                {
                    idBus = pasajero.idBus,
                    ruta = pasajero.ruta,
                    idBusParticipante = pasajero.idBusParticipante,
                    codigo = participante.codigo,
                    nombre = participante.Participante.nombres + " " + participante.Participante.apellidos,
                    tipoDocumento = participante.Participante.DocumentoXParticipante.FirstOrDefault().TipoDocumentoID.nombre,
                    noDocumento = participante.Participante.DocumentoXParticipante.FirstOrDefault().noDocumento
                };
                return Json(new { Result = "OK", Record = addedPasajero });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error CreatePasajero: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al crear pasajero." });
            }
        }

        [HttpPost]
        public JsonResult UpdatePasajero(BusParticipante pasajero)
        {
            try
            {
                ParticipanteXEvento participante = null;
                if (!ModelState.IsValid)
                {
                    AgregarBitacora("Error UpdatePasajero: Formulario inválido");
                    return Json(new
                    {
                        Result = "ERROR",
                        Message = "¡El formulario no es válido! " +
                        "Corrija e intente nuevemente."
                    });
                }
                //comparar participante
                if (pasajero.codigo != null)
                {
                    participante = UoW.participanteXEventoRepository
                        .FindFirst(t => t.codigo == pasajero.codigo.Trim() && t.estado == Constantes.ESTADOPARTICIPANTE_INSCRITO);
                    if (participante != null)
                        pasajero.idParticipanteXEvento = participante.idParticipanteXEvento;
                    else
                    {
                        return Json(new
                        {
                            Result = "ERROR",
                            Message = "¡El participante que ha ingresado es inv&aacute;lido! <br/>" +
                                      "Corrija e intente nuevemente."
                        });
                    }
                }

                //que no hay sido asignado ya
                BusParticipante busp = UoW.busParticipanteRepository
                    .FindFirst(b => b.idParticipanteXEvento == pasajero.idParticipanteXEvento && 
                    b.idBusParticipante != pasajero.idBusParticipante);
                if (busp != null)
                {
                    return Json(new
                    {
                        Result = "ERROR",
                        Message = "¡El participante que ha ingresado ya ha sido asignado a otro bus!"
                    });
                }
                if (participante.Participante.DocumentoXParticipante.Count == 0)
                {
                    return Json(new
                    {
                        Result = "ERROR",
                        Message = "¡El participante no tiene asignado ningún Documento ID! <br/>"
                    });
                }

                //Actualizar pago
                UoW.busParticipanteRepository.Edit(pasajero);
                UoW.Save();
                AgregarBitacora("Actualizacion de pago (UpdatePasajero): " + pasajero.idBusParticipante.ToString());
                return Json(new { Result = "OK" });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error UpdatePasajero: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al actualizar pasajero." });
            }
        }

        [HttpPost]
        public JsonResult DeletePasajero(int idBusParticipante)
        {
            try
            {
                BusParticipante pasajero = UoW.busParticipanteRepository.FindFirst(p => p.idBusParticipante == idBusParticipante);
                Bus bus = UoW.busRepository.FindFirst(b => b.idBus == pasajero.idBus);
                if (bus.Estado == Constantes.ESTADOBUS_CERRADO)
                {
                    bus.Estado = Constantes.ESTADOBUS_ABIERTO;
                    UoW.busRepository.Edit(bus);
                }
                UoW.busParticipanteRepository.Delete(pasajero);
                UoW.Save();
                AgregarBitacora("Eliminación de pago (DeletePasajero): " + idBusParticipante.ToString());
                return Json(new { Result = "OK" });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error DeletePasajero: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al eliminar pasajero." });
            }
        }

        [HttpPost]
        public JsonResult PasajeroList(int idBus, int ruta)
        {
            try
            {
                var pasajeros = UoW.busParticipanteRepository.FindBy(d => d.idBus == idBus && d.ruta == ruta)
                    .Select(p => new
                    {
                        idBus = p.idBus,
                        ruta = p.ruta,
                        idBusParticipante = p.idBusParticipante,
                        codigo = p.ParticipanteXEvento.codigo,
                        nombre = p.ParticipanteXEvento.Participante.nombres + " " + p.ParticipanteXEvento.Participante.apellidos,
                        tipoDocumento = p.ParticipanteXEvento.Participante.DocumentoXParticipante.FirstOrDefault().TipoDocumentoID.nombre,
                        noDocumento = p.ParticipanteXEvento.Participante.DocumentoXParticipante.FirstOrDefault().noDocumento
                    }).ToList();
                var pasajerosCount = pasajeros.Count;
                return Json(new { Result = "OK", Records = pasajeros, TotalRecordCount = pasajerosCount });
            }
            catch (Exception ex)
            {
                AgregarBitacora("Error PasajeroList: " + ex.Message + "--" + ex.Source);
                return Json(new { Result = "ERROR", Message = "Ocurrió un error al obtener listado de pasajeros." });
            }
        }
        #endregion
    }
}
